package com.laivi.basic.model.file.reader;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import com.laivi.basic.common.constants.Constant;
import com.laivi.basic.model.datastruct.ValueMap;
import com.laivi.basic.module.log.Log;
import com.laivi.basic.module.log.Logs;
import com.laivi.basic.util.DataUtil;

public class CsvReader {
	private final static Log log=Logs.getLog(CsvReader.class);
	
	private final static String QUOTATION="\"";
	private File file;
	private boolean hasHeader;
	private String split=",";
	private String[] headers;
	private String coding="utf-8";
	public CsvReader(String path){
		this(path,true);
	}
	
	public CsvReader(File file){
		this(file,true);
	}
	
	public CsvReader(String path,boolean hasHeader){
		this(new File(path),hasHeader);
	}
	
	public CsvReader(File file,boolean hasHeader){
		this.hasHeader=hasHeader;
		this.file=file;
	}
	
	public List<ValueMap> read(String[] fields){
		List<ValueMap> values=new ArrayList<ValueMap>();
		BufferedReader br=null;
		try{
			if(DataUtil.isEmpty(this.coding)){
				br=new BufferedReader(new InputStreamReader(new FileInputStream(file)));
			}else{
				br=new BufferedReader(new InputStreamReader(new FileInputStream(file),this.coding));
			}
			String line=null;
			if(this.hasHeader){
				line=br.readLine();
				headers=replaceAll(line.split(split),QUOTATION,Constant.EMPTY);
			}
			while((line=br.readLine())!=null){
				String [] valueTemp=replaceAll(line.split(split),QUOTATION,Constant.EMPTY);
				ValueMap value=ValueMap.createMap();
				for(int i=0;i<fields.length;i++){
					value.add(fields[i], valueTemp[i]);
				}
				values.add(value);
			}
		}catch(Exception e){
			log.error("error:"+e.getMessage());
		}finally{
			if(br!=null){
				try {
					br.close();
				} catch (IOException e) {
					log.error("error:"+e.getMessage());
				}
			}
		}
		return values;
	}
	
	public List<String[]> read(){
		List<String[]> objs=new ArrayList<String[]>();
		BufferedReader br=null;
		try{
			if(DataUtil.isEmpty(this.coding)){
				br=new BufferedReader(new InputStreamReader(new FileInputStream(file)));
			}else{
				br=new BufferedReader(new InputStreamReader(new FileInputStream(file),this.coding));
			}
			String line=null;
			if(this.hasHeader){
				line=br.readLine();
				headers=replaceAll(line.split(split),QUOTATION,Constant.EMPTY);
			}
			while((line=br.readLine())!=null){
				objs.add(replaceAll(line.split(split),QUOTATION,Constant.EMPTY));
			}
		}catch(Exception e){
			log.error("error:"+e.getMessage());
		}finally{
			if(br!=null){
				try {
					br.close();
				} catch (IOException e) {
					log.error("error:"+e.getMessage());
				}
			}
		}
		return objs;
	}
	
	private String[] replaceAll(String[] values,String regex,String replacement){
		for(int i=0;i<values.length;i++){
			values[i]=values[i].replaceAll(regex, replacement);
		}
		return values;
	}

	public String[] getHeaders() {
		return headers;
	}

	public void setCoding(String coding) {
		this.coding = coding;
	}
	
}